import dayjs from "dayjs";
import NavBar from "@/components/NavBar";
import Textarea from "@/components/Textarea";
import { useAppDispatch, useAppSelector } from "@/hooks";
import {
  getUserProfile,
  loginAction,
  logoutAction,
  updatePhotoAction,
  updateProfileAction,
} from "@/store/action/user";
import { Dialog, List, Popup, Toast, DatePicker } from "antd-mobile";
import React, { useEffect, useRef, useState } from "react";
import styles from "./index.module.scss";
import Input from "@/components/Input";

// 导入 用户资料类型
import { Profile } from "@/store/reducers/user";
import { PickerDate } from "antd-mobile/es/components/date-picker/util";
import history from "@/utils/history";
// 定义 操作的字段的类型
type EditType = "photo" | "gender" | "name" | "intro";

export default function ProfileEdit() {
  const dispatch = useAppDispatch();

  // 获取用户资料
  useEffect(() => {
    dispatch(getUserProfile());
  }, []);

  // 获取 redux中获取数据
  const { profile } = useAppSelector((state) => state.user);

  // 弹出层 显示隐藏 状态
  const [visible, setVisible] = useState(false);

  // 弹出层 昵称和简介
  const [rightVisible, setRightVisible] = useState(false);

  // 昵称表单 字段
  const [name, setName] = useState("");

  // 简介表单 字段
  const [intro, setIntro] = useState("");

  // 操作的字段类型  性别 还是 头像 、昵称、简介 约束了类型
  const [editType, setEditType] = useState<EditType>("photo");

  // 存储 文件选择框 ref
  const inputRef = useRef({} as HTMLInputElement);

  // 控制 日期选择器 显示和隐藏
  const [pickShow, setPickShow] = useState(false);

  // 控制popup显示
  const handleShowPopup = (editType: EditType) => {
    setVisible(true);
    setEditType(editType); // 设置当前要显示的字段的名称
  };
  // 控制popup组件隐藏
  const handleHidePopup = () => {
    setVisible(false);
  };

  // 点击 拍照或者本地文件
  const handleUploadFile = () => {
    // 调出 文件选择框 让用户选择文件！！
    // console.dir(inputRef.current);
    // 模拟用户 点击  文件夹选择框
    inputRef.current.click();
  };

  // 文件选择框 监听到文件上传了， 发送给后端
  const handleUpLoad = async (ev: React.ChangeEvent<HTMLInputElement>) => {
    // console.log(ev);

    // 获取上传到浏览器内存中的文件
    if (ev.target.files?.length) {
      const file = ev.target.files[0];
      // 走一遍 文件上传的流程
      // 1 new一个 formData 对象
      const fd = new FormData();
      // 2 formData.append 来添加上传的文件
      fd.append("photo", file);
      // 3 通过 请求 把文件发送给后端 .....
      await dispatch(updatePhotoAction(fd));
      // 4 。。。。弹出窗口提醒用户、刷新页面 关闭蒙版。。。。。
      setVisible(false);
      Toast.show({ content: "更新头像成功" });
      // 刷新页面
      dispatch(getUserProfile());
    }
  };

  // 希望 只要是编辑用户资料 都使用同一个action
  // dispatch(updateProfileAction({gender}))
  // dispatch(updateProfileAction({name}))
  // dispatch(updateProfileAction({intro}))

  // 编辑性别
  // const handleChangeGender = (gender: string) => {
  // console.log(gender);
  // 假设代码

  // 编辑性别
  // dispatch(updateProfileAction(gender))

  // 编辑昵称
  // dispatch(updateProfileAction(name))
  // };

  // 编辑用户资料 性别编辑
  // 类型 可选 => 把类型里面的每一个属性都转成 可选
  const handleUpdateProfile = async (profile: Partial<Profile>) => {
    // actionCreater 函数 来发送异步acion 来编辑数据
    await dispatch(updateProfileAction(profile));
    setVisible(false); // 底下 往上显示的   头像和性别使用
    setRightVisible(false); // 右往左 显示  昵称和简介
    setPickShow(false); // 日期选择框 关闭
    Toast.show({ content: "更新成功" });
    dispatch(getUserProfile());
  };

  // 昵称和简介 提交事件
  const handleSubmit = async () => {
    /* 
    1 先判断出来 操作的是昵称还是简介
    2 再去构造参数
    3 最后 调用 handleUpdateProfile 来完成编辑
     */
    if (editType === "name") {
      // 你现在编辑的时昵称
      handleUpdateProfile({ name });
    } else if (editType === "intro") {
      // 你现在编辑的是 简介
      handleUpdateProfile({ intro });
    }
  };

  // 点击昵称和简介
  const handleShowRightPopup = (editType: EditType) => {
    // 设置 昵称编辑菜单 显示旧的数据
    setName(profile.name);
    // 设置 简介编辑菜单 显示旧的数据
    setIntro(profile.intro);
    setRightVisible(true);
    setEditType(editType); // 设置当前要显示的字段的名称
  };

  // 日期选择器 取消事件
  const handlePickerCancel = () => {
    setPickShow(false);
  };
  // 日期选择器  确定事件
  const handlePickerConfirm = (ev: PickerDate) => {
    // console.dir(typeof ev);// ev 是日期对象
    // console.log(dayjs(ev).format("YYYY-MM-DD"));
    const birthday = dayjs(ev).format("YYYY-MM-DD");
    handleUpdateProfile({ birthday });
  };

  const handleLogOut = () => {
    /* 
    1 弹出确认框 询问用户 是否退出
    2 清除
      1 redux中  auth
      2 本地存储中 auth
    3 弹出用户 清除完毕
    4 重新跳转到登录页面 
     */

    Dialog.confirm({
      content: "您确定退出吗",
      onConfirm() {
        dispatch(logoutAction());
        Toast.show({ content: "退出成功" });
        setTimeout(() => {
          history.push("/login");
        }, 1500);
      },
    });
  };

  return (
    <div className={styles.root}>
      <div className="content">
        {/* 顶部导航栏 */}
        <NavBar>个人资料</NavBar>

        <div className="wrapper">
          {/* 列表一：显示头像、昵称、简介 */}
          <List className="profile-list">
            <List.Item
              arrow
              extra={<img className="avatar" src={profile.photo} alt="" />}
              onClick={() => handleShowPopup("photo")}
            >
              头像
            </List.Item>

            <List.Item
              arrow
              extra={profile.name}
              onClick={() => handleShowRightPopup("name")}
            >
              昵称
            </List.Item>
            <List.Item
              arrow
              onClick={() => handleShowRightPopup("intro")}
              extra={<span className="intro">{profile.intro || "未填写"}</span>}
            >
              简介
            </List.Item>

            <List.Item
              arrow
              extra={profile.gender === 0 ? "男" : "女"}
              onClick={() => handleShowPopup("gender")}
            >
              性别
            </List.Item>
            <List.Item
              arrow
              extra={profile.birthday}
              onClick={() => setPickShow(true)}
            >
              生日
            </List.Item>
          </List>

          {/* 文件选择框，用于头像图片的上传 */}
          <input
            ref={inputRef}
            onChange={handleUpLoad}
            className="avatar-upload"
            type="file"
          />
        </div>

        {/* 底部栏：退出登录按钮 */}
        <div className="logout">
          <button className="btn" onClick={handleLogOut}>
            退出登录
          </button>
        </div>

        {/* 底部弹出层 */}
        <Popup
          visible={visible}
          position="bottom"
          bodyClassName="popup-bottom-list"
          onMaskClick={handleHidePopup}
        >
          {editType === "photo" && (
            <>
              {" "}
              <div className="list-item" onClick={handleUploadFile}>
                拍照
              </div>
              <div className="list-item" onClick={handleUploadFile}>
                本地选择
              </div>
            </>
          )}
          {editType === "gender" && (
            <>
              {" "}
              <div
                className="list-item"
                onClick={() => handleUpdateProfile({ gender: 0 })}
              >
                男
              </div>
              <div
                className="list-item"
                onClick={() => handleUpdateProfile({ gender: 1 })}
              >
                女
              </div>
            </>
          )}
          <div className="list-item" onClick={handleHidePopup}>
            取消
          </div>
        </Popup>

        {/* 右侧弹出层 */}
        <Popup
          visible={rightVisible}
          position="right"
          bodyClassName="popup-right"
        >
          <NavBar
            onBack={() => setRightVisible(false)}
            right={
              <span className="submit-btn" onClick={handleSubmit}>
                提交
              </span>
            }
          >
            编辑用户信息
          </NavBar>
          <div className="edit-content">
            {editType === "name" && (
              <>
                <h3 className="edit-title">编辑昵称</h3>
                <Input
                  value={name}
                  onChange={(ev) => setName(ev.target.value)}
                  className="edit-input"
                />
              </>
            )}
            {editType === "intro" && (
              <>
                <h3 className="edit-title">编辑简介</h3>
                <Textarea
                  value={intro}
                  onChange={(ev) => setIntro(ev.target.value)}
                />
              </>
            )}
          </div>
        </Popup>

        {/* 日期选择器 */}
        <DatePicker
          visible={pickShow}
          min={new Date("1960-01-01")}
          max={new Date()}
          value={new Date(profile.birthday)}
          onCancel={handlePickerCancel}
          onConfirm={handlePickerConfirm}
        />
      </div>
    </div>
  );
}
